home *** CD-ROM | disk | FTP | other *** search
- /*
- * ntchange.c
- *
- * Copyright (C) 1995-1997, 1999 Martin von L÷wis
- * Copyright (C) 1997 RΘgis Duchesne
- */
-
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
-
- #include <stdio.h>
- #ifdef HAVE_GETOPT_H
- #include <getopt.h>
- #else
- #define getopt_long(a,v,o,ol,x) getopt(a,v,o)
- #endif
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include <sys/stat.h>
- #ifdef HAVE_FCNTL_H
- #include <fcntl.h>
- #endif
- #ifdef HAVE_IO_H
- #include <io.h>
- #endif
- #include <string.h>
- #include <stdlib.h>
- #include "ntfstypes.h"
- #include "struct.h"
- #include "util.h"
- #include "nttools.h"
- #include "inode.h"
- #include "super.h"
- #include "attr.h"
-
- char *short_opts="a:d:W:t:i:A:L:n:V";
- #ifdef HAVE_GETOPT_H
- struct option options[]={
- {"alloc-clusters",1,0,'a'},
- {"dealloc-clusters",1,0,'d'},
- {"write-inode",1,0,'W'},
- {"truncate",1,0,'t'},
- {"inum",1,0,'i'},
- {"anum",1,0,'A'},
- {"symlink",1,0,'L'},
- {"new-file",1,0,'n'},
- {"version",0,0,'V'},
- {0,0,0,0}
- };
- #endif
-
- void my_perror(const char* msg,int error)
- {
- fprintf(stderr,"%s:%s\n",msg,strerror(error));
- exit(1);
- }
-
- int usage(void)
- {
- fprintf(stderr,"ntchange [options]\n"
- "-o offset Offset in file\n"
- "-a start size Allocate cluster range\n"
- "-d start size Deallocate cluster range\n"
- "-W inum Read and write inode inum\n"
- "-t newsize truncate inode to newsize\n"
- "-i inum operate on inode inum\n"
- "-A anum operate on attribute anum (80)\n"
- "-L string make inode a symlink with value string\n"
- "-n name create file name in dir inum\n"
- "-V print version\n"
- );
- return 1;
- }
-
- /* print the file ino on stdout */
- void ntfs_change_file(ntfs_inode *ino,char *buf,int offset,int count)
- {
- int position;
- ntfs_io io;
- position=0;
- /* write to the unnamed data attribute */
- io.fn_put=0;
- io.fn_get=0; /* we don't need copyfunctions here */
- io.param=buf;
- io.size=count;
- ntfs_write_attr(ino,ino->vol->at_data,NULL,offset,&io);
- }
-
- int main(int argc,char *argv[])
- {
- int c,error;
- char device[256]={'\0'};
- char *it;
- char *source=0;
- char *name=0;
- void *buf;
- int fsource;
- ntfs_volume *volume;
- ntfs_inode ino;
- int inum=-1;
- int offset=0;
- int alloc_start = -2;
- int alloc_size=0,dealloc_start=-2;
- int Winum=0;
- int truncate=-2,anum=0x80;
- char *symlink=0;
- char *newfile=0;
- struct stat sb;
- extern int optind,opterr;
- extern char* optarg;
- ntfs_attribute *attr;
-
- opterr=1;
- while((c=getopt_long(argc,argv,short_opts,options,NULL))>0)
- switch(c)
- {
- case 'o': offset=strtol(optarg,NULL,0);break;
- case 'a': alloc_start=strtol(optarg,NULL,0);
- alloc_size=strtol(argv[optind++],NULL,0);
- break;
- case 'd': dealloc_start=strtol(optarg,NULL,0);
- alloc_size=strtol(argv[optind++],NULL,0);
- break;
- case 'W': Winum=strtol(optarg,NULL,0);break;
- case 't': truncate=strtol(optarg,NULL,0);break;
- case 'i': inum=strtol(optarg,NULL,0);break;
- case 'A': anum=strtol(optarg,NULL,0);break;
- case 'L': symlink=optarg;break;
- case 'n': newfile=optarg;break;
- case 'V': printf("ntdir " NTFS_VERSION "\n");exit(0);break;
- default: usage();exit(0);
- }
- if(optind+2!=argc){
- usage();
- exit(1);
- }
- source=argv[optind];
- name=argv[optind+1];
- for(it=name+2;*it && *it!='/';it++)
- /*nothing*/;
- if(it!=name+2)
- {
- strcpy(device,"/dev/");
- strncpy(device+5,name+2,(it-name)-2);
- device[(it-name)+3]='\0';
- }
- name=it;
- if(*name=='/')name++;
- volume=ntfs_open_volume(device,0,1,0);
- if(!volume)return 1;
- volume->nct=nct_utf8;
- if(alloc_start!= -2){
- ntfs_cluster_t st = alloc_start;
- error=ntfs_allocate_clusters(volume,&st,&alloc_size,0);
- if(error)my_perror("allocate",error);
- printf("Got range %x+%x\n",
- (unsigned int)st, alloc_size);
- return 0;
- }
- if(dealloc_start!= -2){
- error=ntfs_deallocate_clusters(volume,dealloc_start,alloc_size);
- if(error)my_perror("deallocate",error);
- return 0;
- }
- if(Winum){
- error=ntfs_init_inode(&ino,volume,Winum);
- if(error)my_perror("winum",error);
- error=ntfs_update_inode(&ino);
- if(error)my_perror("winum",error);
- return 0;
- }
- if(truncate!=-2){
- if(inum==-1){
- usage();
- return 1;
- }
- error=ntfs_init_inode(&ino,volume,inum);
- if(error)my_perror("init",error);
- attr=ntfs_find_attr(&ino,anum,0);
- if(!attr){
- fprintf(stderr,"Inode %x has no attribute %x\n",inum,anum);
- return 1;
- }
- error=ntfs_resize_attr(&ino,attr,truncate);
- if(error)my_perror("resize",error);
- error=ntfs_update_inode(&ino);
- if(error)my_perror("writeback",error);
- return 0;
- }
- if(symlink){
- unsigned short *data;
- int nlen;
- ntfs_attribute* aresult;
- if(inum<0){
- fprintf(stderr,"No inum given to for symlink");
- return 1;
- }
- nlen=strlen(symlink);
- data=malloc(nlen*2+2);
- ntfs_ascii2uni(data,symlink,nlen);
- error=ntfs_init_inode(&ino,volume,inum);
- if(error)my_perror("init",error);
- error=ntfs_create_attr(&ino,volume->at_symlink,0,
- data,nlen*2,&aresult);
- if(error)my_perror("create symlink",error);
- attr=ntfs_find_attr(&ino,volume->at_standard_information,0);
- NTFS_PUTU8((ntfs_u8*)attr->d.data+8, 0x40);
- error=ntfs_update_inode(&ino);
- if(error)my_perror("writeback",error);
- return 0;
- }
- if(newfile){
- ntfs_inode dir;
- if(inum<0){
- fprintf(stderr,"no dir given for newfile\n");
- return 1;
- }
- error=ntfs_init_inode(&dir,volume,inum); /* FIXME: check for dir */
- if(error)my_perror("init",error);
- error=ntfs_alloc_file(&dir,&ino,newfile,strlen(newfile));
- if(error)my_perror("create new file",error);
- error=ntfs_update_inode(&ino);
- if(error)my_perror("writeback",error);
- error=ntfs_update_inode(&dir);
- if(error)my_perror("directory writeback",error);
- fprintf(stderr,"allocated inode %x\n",ino.i_number);
- /*error=ntfs_dir_add1(&dir,newfile,strlen(newfile),&ino);
- if(error){
- fprintf(stderr,"error %x when modifying directory\n",
- error);
- return 1;
- }
- */
- return 0;
- }
-
- if(!source)
- return usage();
- #ifdef MSDOS
- fsource=open(source,O_RDONLY|O_BINARY);
- #else
- fsource=open(source,O_RDONLY);
- #endif
- if(fsource==-1)
- {
- perror(source);
- return 1;
- }
- if(fstat(fsource,&sb)!=0)
- {
- perror(source);
- return 1;
- }
- buf=malloc(sb.st_size);
- if(!buf)
- {
- perror(argv[0]);
- return 1;
- }
- if(read(fsource,buf,sb.st_size)!=sb.st_size)
- {
- perror(argv[0]);
- return 1;
- }
- inum=5;
- /* walk the directory tree */
- do{
- char *next;
- error=ntfs_init_inode(&ino,volume,inum);
- if(error)my_perror("init",error);
- if(!name || !*name)break;
- next=strpbrk(name,NTFS_PATH_SEP);
- if(next){
- *next='\0';
- next++;
- }
- inum=ntfs_find_file(&ino,name);
- if(inum==-1){
- printf("%s not found\n",name);
- return 1;
- }
- name=next;
- }while(1);
- ino.i_number=inum;
- ntfs_change_file(&ino,buf,offset,sb.st_size);
- return 0;
- }
-
- /*
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
-